package com.tally.file.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ListObjectsV2Result;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.PutObjectRequest;
import com.tally.server.config.ConstKey;
import com.tally.server.dto.EverydayCostDTO;
import com.tally.server.dto.EverydayIncomeDTO;
import com.tally.server.dto.FileDTO;
import com.tally.server.dto.ResponseDTO;
import com.tally.server.enums.FileUseEnum;
import com.tally.server.service.CostService;
import com.tally.server.service.ExcelService;
import com.tally.server.service.FileService;
import com.tally.server.service.IncomeService;
import com.tally.server.utils.UUIDUtil;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: sy
 * @Date: 2021/1/27 22:39
 * @Description:
 */
@RestController
@RequestMapping("/file")
public class FileController {
    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    public static final String BUSINESS_NAME = "文件操作";

    @Value("${oss.accessKeyId}")
    private String accessKeyId;

    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${oss.endpoint}")
    private String endpoint;

    @Value("${oss.ossDomain}")
    private String ossDomain;

    @Value("${oss.bucket}")
    private String bucket;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private FileService fileService;

    @Autowired
    private CostService costService;

    @Autowired
    private IncomeService incomeService;

    @Autowired
    private ExcelService excelService;

    @PostMapping("/oss-simple")
    public ResponseDTO fileUpload(@RequestParam MultipartFile file, String use) throws IOException {
        logger.info("上传文件开始-simple");
        FileUseEnum useEnum = FileUseEnum.getByCode(use);
        String key = UUIDUtil.getShortUUID();
        String fileName = file.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();
        String dir = useEnum.name().toLowerCase();
        String path = dir + "/" + key + "." + suffix;

        OSS ossClient = new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket,path,new ByteArrayInputStream(file.getBytes()));
        ossClient.putObject(putObjectRequest);
        FileDTO fileDTO = new FileDTO();

        logger.info("保存文件记录开始");
        fileDTO.setName(fileName);
        fileDTO.setSuffix(suffix);
        fileDTO.setSize((int) file.getSize());
        fileDTO.setPath(path);
        fileDTO.setKey(key);
        fileDTO.setUse(use);
        fileService.save(fileDTO);

        fileDTO.setPath(ossDomain + "/" + path);
        return ResponseDTO.success(fileDTO);
    }

    @GetMapping("/get-default-photo")
    public ResponseDTO getDefaultPhoto(){
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 列举文件。如果不设置KeyPrefix，则列举存储空间下的所有文件。如果设置KeyPrefix，则列举包含指定前缀的文件。
        ListObjectsV2Result result = ossClient.listObjectsV2(bucket);
        List<OSSObjectSummary> ossObjectSummaries = result.getObjectSummaries();
        List<OSSObjectSummary> ossObjectSummaryList = ossObjectSummaries.stream().skip(1).filter(s -> s.getKey().startsWith("default-photo")).collect(Collectors.toList());
        List<String> photoList = new ArrayList<>();
        for(OSSObjectSummary o:ossObjectSummaryList){
            photoList.add(ossDomain + "/" + o.getKey());
        }
// 关闭OSSClient。
        ossClient.shutdown();

        return ResponseDTO.success(photoList);
    }

    @GetMapping("/excel/download/{type}")
    public void downloadExcel(HttpServletResponse response,
                              @PathVariable String type,
                              @RequestParam("start") String start,
                              @RequestParam("end") String end) throws ParseException, IOException {
        Date startDate = DateUtils.parseDate(start, "yyyy-MM-dd");
        Date endDate = DateUtils.parseDate(end, "yyyy-MM-dd");
        JSONObject jsonObject = getLoginUser();
        if (jsonObject == null) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return;
        }
        Integer userId = jsonObject.getInteger("id");

        HSSFWorkbook wb = null;
        if ("cost".equals(type)) {
            List<EverydayCostDTO> everydayCostDTOList = costService.getEverydayList(startDate, endDate, userId);
            if (CollectionUtils.isEmpty(everydayCostDTOList)) {
                response.setStatus(HttpStatus.NO_CONTENT.value());
                return;
            }
            logger.info("{}",everydayCostDTOList);
            wb = excelService.downloadCostExcel(everydayCostDTOList);
        } else if("income".equals(type)) {
            List<EverydayIncomeDTO> everydayIncomeDTOList = incomeService.getEverydayList(startDate, endDate, userId);
            if (CollectionUtils.isEmpty(everydayIncomeDTOList)) {
                response.setStatus(HttpStatus.NO_CONTENT.value());
                return;
            }
            logger.info("{}", everydayIncomeDTOList);
            wb = excelService.downloadIncomeExcel(everydayIncomeDTOList);
        } else {
            throw new IllegalArgumentException();
        }

        OutputStream output = response.getOutputStream();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");

        wb.write(output);
        output.close();
    }
    private JSONObject getLoginUser() {
        String token = request.getHeader("token");
        String jsonString =(String) redisTemplate.opsForValue().get(token + ConstKey.LOGIN_SUFFIX);
        return JSONObject.parseObject(jsonString);
    }
}
